package com.liming.common.util;

import cn.hutool.jwt.*;
import cn.hutool.jwt.signers.JWTSigner;
import cn.hutool.jwt.signers.JWTSignerUtil;
import com.liming.common.constant.SystemConstants;
import lombok.extern.slf4j.Slf4j;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import static com.liming.common.constant.TimeConstants.TOKEN_EXPIRE_TIME;

/**
 * @author liming
 * @date 2025/1/10
 */
@Slf4j
public class JwtUtils {

    private final static String KEY = "lm0319";

    /**
     * 获取JWT签证器
     *
     * @return JWTSigner签证器
     */
    public static JWTSigner getJWTSigner() {
        return JWTSignerUtil.hs256(KEY.getBytes());
    }

    /**
     * 设置并获取JWT载荷
     *
     * @param data 载荷
     * @return 载荷
     */
    public static <T> Map<String, T> setPayload(String key, T data) {
        Map<String, T> payload = new HashMap<>();
        payload.put(key, data);
        return payload;
    }

    public static <T> Map<String, T> setHeader(String key, T data) {
        Map<String, T> header = new HashMap<>();
        header.put(key, data);
        return header;
    }

    /**
     *
     * @param hK 头部Key
     * @param hV 头部数据
     * @param pK 载荷Key
     * @param pV 载荷数据
     * @return Token
     * @param <T> 数据类型
     */
    public static <T> String getToken(String hK, T hV, String pK, T pV) {
        JWT jwt = JWT.create()
                .addHeaders(setHeader(hK, hV))
                .addPayloads(setPayload(pK, pV))
                .setSigner(getJWTSigner())
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .setExpiresAt(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME));
        return jwt.sign();
    }

    /**
     * 解析Token为JWT
     *
     * @param token Token
     * @return JWT
     */
    public static JWT parseToken(String token) {
        return JWT.of(token);
    }

    public static String getKoiHeader(String token) {
        JWTHeader header = parseToken(token).getHeader();
        Object koi = header.getClaim(SystemConstants.KOI);
        if (koi instanceof String) {
            return (String) koi;
        }
        return null;
    }

    /**
     * 从Token中的载荷获取String值
     *
     * @param token Token
     * @return 载荷Value
     */
    public static String getIdFromToken(String token) {
        JWTPayload payload = parseToken(token).getPayload();
        Object id = payload.getClaim(SystemConstants.ID);
        if (id instanceof String) {
            return (String) id;
        }
        return id.toString();
    }

    /**
     * 校验Token （时间 & 有效性）
     *
     * @param token Token
     * @return 验证结果
     */
    public static boolean verify(String token) {
        log.info("验证Token");
        JWTValidator.of(token).validateDate();
        JWTUtil.verify(token, getJWTSigner());
        return true;
    }

    // 失效
    public static void invalid(String token) {
        JWTUtil.parseToken(token).setIssuedAt(new Date(System.currentTimeMillis() + TOKEN_EXPIRE_TIME));
    }
}
